﻿using System;
using System.Drawing;
using SdlDotNet.Graphics;
using NielsRask.K242.Core;

namespace RenderTest1
{
    class TerrainLayer : LayerBase
    {
        Size size;
        Surface surface;
        Asteroid asteroid;

        IsoEngine isoEngine;
        SurfaceCollection tiles;

        public TerrainLayer(Size size, Asteroid asteroid)
		{
			this.surface = new Surface( size );
            this.asteroid = asteroid;
            this.size = size;
            isoEngine = new IsoEngine( 24,48, @"..\..\Data\48x96\MouseMap.gif", new Point(200,0) );
            tiles = new SurfaceCollection();
            tiles.Add(new Surface(@"..\..\Data\48x96\Terrain1.bmp"));
            tiles.Add(new Surface(@"..\..\Data\48x96\Terrain2.bmp"));
            tiles.Add(new Surface(@"..\..\Data\48x96\Terrain3.bmp"));
            tiles.TransparentColor = Color.Black;
            tiles.Transparent = true;

		}
		public override bool RegisterClick( SdlDotNet.Input.MouseButtonEventArgs e )
        {
            return false;
           // return base.RegisterClick();
        }

        public override Surface RenderSurface()
        {
            surface = new Surface(size);
            surface.Fill(Color.MidnightBlue);   // evt. navy? darkblue?
            //surface.TransparentColor = Color.Black;


            // terrain layer blitting
            for (int i = 0; i < asteroid.Terrain.GetLength(0); i++)
            {
                for (int j = 0; j < asteroid.Terrain.GetLength(1); j++)
                {
                    Point p = isoEngine.Diamond_TilePlotter(new Point(i, j));

                    //Console.WriteLine("blitter " + (int)asteroid.Terrain[i, j] + " til " + p);
                    //surface.Blit(tiles[(int)asteroid.Terrain[i, j]], p);
                    surface.Blit(tiles[0], p);
                }
            }
            //surface.Update();
            //surface.refr
            return surface;
        }
    }


    public class IsoEngine
    {
        readonly int TileHeight = 24;//20;
        readonly int TileWidth = 48;//40;
        private Point ptScreenAnchor;// = new Point( screen.200, 200 );	// screen anchor

        private Surface mouseMap;// = new Surface(@"c:\data\k242\48x96\MouseMap.gif");

        public IsoEngine(int tileHeight, int tileWidth, string mouseMapPath, Point ptScreenAnchor)
        {
            this.TileHeight = tileHeight;
            this.TileWidth = tileWidth;
            mouseMap = new Surface(mouseMapPath);
            this.ptScreenAnchor = ptScreenAnchor;
        }

        #region ISO Engine

        // world coord to map coord
		/// <summary>
		/// Maps a screen coordinate to a map coordinate
		/// </summary>
		/// <param name="ptMouse"></param>
		/// <returns></returns>
        public Point Diamond_MouseMapper(Point ptMouse)
        {
            //			Console.WriteLine("now in mousemapper ");
            // step 1
            //ptMouse.X -= ptScreenAnchor.X;
            //ptMouse.Y -= ptScreenAnchor.Y;

            // step 2
            Point ptMap = new Point(2, 2);
            Point ptPlot = Diamond_TilePlotter(ptMap);

            ptMouse.X -= ptPlot.X;
            ptMouse.Y -= ptPlot.Y;
            //ptMouse.Y -= 48;
            //ptMouse.Y -= 48;

            //			Console.WriteLine("step2 ptPlot: "+ptPlot);
            //			Console.WriteLine("step2 ptMouse: "+ptMouse);

            // step 3
            int MouseMapWidth = 48;//40;
            int MouseMapHeight = 24;//20;

            Point ptMouseMapCoarse = new Point((ptMouse.X / MouseMapWidth), (ptMouse.Y / MouseMapHeight));
            Point ptMouseMapFine = new Point((ptMouse.X % MouseMapWidth), (ptMouse.Y % MouseMapHeight));

            if (ptMouseMapFine.X < 0)
            {
                ptMouseMapFine.X += MouseMapWidth;
                ptMouseMapCoarse.X--;
            }
            if (ptMouseMapFine.Y < 0)
            {
                ptMouseMapFine.Y += MouseMapHeight;
                ptMouseMapCoarse.Y--;
            }
            //			Console.WriteLine("step3 coarse:"+ptMouseMapCoarse );
            //			Console.WriteLine("step3 fine:"+ptMouseMapFine );

            // step 4
            ptMap = new Point(0, 0);

            while (ptMouseMapCoarse.Y < 0)
            {
                ptMap = Diamond_TileWalker(ptMap, IsoDirection.North);
                ptMouseMapCoarse.Y++;
            }
            while (ptMouseMapCoarse.Y > 0)
            {
                ptMap = Diamond_TileWalker(ptMap, IsoDirection.South);
                ptMouseMapCoarse.Y--;
            }
            while (ptMouseMapCoarse.X < 0)
            {
                ptMap = Diamond_TileWalker(ptMap, IsoDirection.West);
                ptMouseMapCoarse.X++;
            }
            while (ptMouseMapCoarse.X > 0)
            {
                ptMap = Diamond_TileWalker(ptMap, IsoDirection.East);
                ptMouseMapCoarse.X--;
            }
            //			Console.WriteLine("step4: "+ptMap);

            // step 5
            //mouseMap.Lock();
            Color mmColor = mouseMap.GetPixel(ptMouseMapFine);
            //mouseMap.Unlock();
            //Console.WriteLine("mouseMap color is "+mmColor.Name);
            if (mmColor == Color.FromArgb(255, 0, 0))
            {
                //Console.WriteLine( "mmColor=Red" );
                ptMap = Diamond_TileWalker(ptMap, IsoDirection.NorthWest);
            }
            else if (mmColor == Color.FromArgb(255, 255, 0))
            {
                //Console.WriteLine( "mmColor=Yellow" );
                ptMap = Diamond_TileWalker(ptMap, IsoDirection.NorthEast);
            }
            else if (mmColor == Color.FromArgb(0, 255, 0))
            {
                //Console.WriteLine( "mmColor=Green" );
                ptMap = Diamond_TileWalker(ptMap, IsoDirection.SouthWest);
            }
            else if (mmColor == Color.FromArgb(0, 0, 255))
            {
                //Console.WriteLine( "mmColor=Blue" );
                ptMap = Diamond_TileWalker(ptMap, IsoDirection.SouthEast);
            }

            return ptMap;

        }

		/// <summary>
		/// Maps a map coordinate to a screen coordinate
		/// </summary>
		/// <param name="ptMap"></param>
		/// <returns></returns>
        public Point Diamond_TilePlotter(Point ptMap)
        {
            Point screenpoint = new Point(0, 0);
            screenpoint.X = ptScreenAnchor.X + (ptMap.X - ptMap.Y) * TileWidth / 2;
            screenpoint.Y = ptScreenAnchor.Y + (ptMap.X + ptMap.Y) * TileHeight / 2;
            return screenpoint;
        }

		/// <summary>
		/// Returns the map position that is the result of a move from another position
		/// </summary>
		/// <param name="ptMap"></param>
		/// <param name="direction"></param>
		/// <returns></returns>
        public static Point Diamond_TileWalker(Point ptMap, IsoDirection direction)
        {
            switch (direction)
            {
                case IsoDirection.East:
                    ptMap.X++;
                    ptMap.Y--;
                    break;
                case IsoDirection.North:
                    ptMap.X--;
                    ptMap.Y--;
                    break;
                case IsoDirection.NorthEast:
                    ptMap.Y--;
                    break;
                case IsoDirection.NorthWest:
                    ptMap.X--;
                    break;
                case IsoDirection.South:
                    ptMap.X++;
                    ptMap.Y++;
                    break;
                case IsoDirection.SouthEast:
                    ptMap.X++;
                    break;
                case IsoDirection.SouthWest:
                    ptMap.Y++;
                    break;
                case IsoDirection.West:
                    ptMap.X--;
                    ptMap.Y++;
                    break;
            }
            return ptMap;
        }


        #endregion

    }
    public enum IsoDirection
    {
        NorthWest,
        North,
        NorthEast,
        East,
        SouthEast,
        South,
        SouthWest,
        West
    }


}
